// 《围棋》作者版权所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package objabi

import "strings"

// PathToPrefix将原始字符串转换为将在
// 符号表中使用的前缀。所有控制字符，空格，“%”和““'，以及
// 非7位干净字节变成%xx。周期只需要在路径的最后一段中转义，如果我们将其转义为
// 尽可能少的话，它会让用户更快乐。
func PathToPrefix(s string) string {
	slash := strings.LastIndex(s, "/")
	// 检查需要转义的字符
	n := 0
	for r := 0; r < len(s); r++ {
		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
			n++
		}
	}

	// 快速退出
	if n == 0 {
		return s
	}

	// 转义
	const hex = "0123456789abcdef"
	p := make([]byte, 0, len(s)+2*n)
	for r := 0; r < len(s); r++ {
		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
			p = append(p, '%', hex[c>>4], hex[c&0xF])
		} else {
			p = append(p, c)
		}
	}

	return string(p)
}

// IsRuntimePackagePath检查'pkgpath'，如果它
// 属于“运行时相关”包的集合，则返回TRUE，包括
// /“运行时”本身、“反射”、“syscall”和
// /“运行时/内部/*”包。
// /中的编译器和/或汇编程序在构建这样的
// /包时需要注意一些情况，例如，在
// /汇编源中启用ABI选择器等功能。
// 
// 与cmd/dist/build保持同步。开始：IsRuntimePackagePath。
func IsRuntimePackagePath(pkgpath string) bool {
	rval := false
	switch pkgpath {
	case "runtime":
		rval = true
	case "reflect":
		rval = true
	case "syscall":
		rval = true
	case "internal/bytealg":
		rval = true
	default:
		rval = strings.HasPrefix(pkgpath, "runtime/internal")
	}
	return rval
}
